#include <iostream>
#include <string>
#include <regex>

int main()
{
    // HTTP请求格式： GET /mysite/login?user=zhangsan&pass=123123 HTTP/1.1\r\n
    std::string str = "GET /mysite/login?user=zhangsan&pass=123123 HTTP/1.1\r\n";
    std::smatch matches;
    // 请求方法的匹配：GET HEAD POST PUT DELETE 等
    // ^?代表的是非 ? 字符才进行匹配，([^?]*) 中的 * 代表的是这个非问号字符应该匹配一次或多次
    // .* 表示前面的字符串匹配规则结束之后，之后的匹配都不关心
    // (?:\\?(.*))?  需要分为几部分来看
    //      第一部分：\\?       \\? 表示原始的问号字符，.*表示提取问号之后的任意字符0次或者多次，直到遇到空格
    //      第二部分：.*        .*  表示提取str中的 ? 0次或多次
    //      第三部分：?:        ?:  表示匹配问号，但是不提取
    // (HTTP/1\\.[01]) 表示匹配从HTTP/1.开始，后面有个 0 或 1 的字符串
    // (?:\n|\r\n)? 中的第一个问号配合冒号 形成的?:表示匹配某个字符串，但不提取，
    //      比如这里就是匹配\n 或 \r\n，但不提取，
    // (?:\n|\r\n)? 中的第二个问号表示匹配前面的表达式或一次，
    // 这样就可以匹配下面三种情况
    //   case1:str = "GET /mysite/login?user=zhangsan&pass=123123 HTTP/1.1";
    //   case2:str = "GET /mysite/login?user=zhangsan&pass=123123 HTTP/1.1\n";
    //   case1:str = "GET /mysite/login?user=zhangsan&pass=123123 HTTP/1.1\r\n";

    // 
    std::regex e("(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\?(.*))? (HTTP/1\\.[01])(?:\n|\r\n)?");
    // 注意                                 ↑                   ↑  这两处的空格也起到了匹配规则的作用    

    bool ret = std::regex_match(str, matches, e);
    if (ret == false)
    {
        return -1;
    }
    for (auto& s : matches)
    {
        std::cout << s << std::endl;
    }
    
}
